home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.3 Development Libraries / SGI IRIX 6.3 Development Libraries.iso / dist6.3 / gl_dev.idb / usr / share / src / OpenGL / teach / motif / vertarray.c.z / vertarray.c
Encoding:
C/C++ Source or Header  |  1996-12-06  |  6.6 KB  |  257 lines

  1. /*
  2.  * vertarray - simple demo of the vertex array extension.
  3.  */
  4. /* compile:  cc -o vertarray vertarray.c -lGLw -lGLU -lGL -lXm -lXt -lX11 */
  5.  
  6. #include <GL/glx.h>
  7. #include <GL/glu.h>
  8. #include <Xm/Frame.h>
  9. #include <Xm/RowColumn.h>
  10. #include <X11/GLw/GLwMDrawA.h>
  11. #include <X11/keysym.h>
  12. #include <X11/Xutil.h>
  13. #include <math.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. static int attributeList[] = {GLX_RGBA, GLX_RED_SIZE, 1, GLX_DEPTH_SIZE, 4, None};
  19.  
  20. static String fallbackResources[] = {
  21.     "*sgiMode: True",
  22.     "*useSchemes: all",
  23.     "*glxwidget.width: 300", "*glxwidget.height: 300",
  24.     "*frame.shadowType: SHADOW_IN",
  25.     NULL,
  26. };
  27.  
  28.  
  29. /* number of strips into which the grid should be subdivided */
  30. #define SIZE 21
  31.  
  32. GLfloat vertexes[SIZE][SIZE][2][3];
  33. GLubyte colors[SIZE][SIZE][2][3];
  34. GLfloat normals[SIZE][SIZE][2][3];
  35.  
  36. int lighting = 0, faces = 1;
  37.  
  38. static void 
  39. reshape(Widget w, XtPointer client_data, XtPointer call)
  40. {
  41.     GLwDrawingAreaCallbackStruct *call_data;
  42.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  43.  
  44.     glViewport(0, 0, call_data->width, call_data->height);
  45. }
  46.  
  47. static void 
  48. draw_scene(Widget w, XtPointer client_data, XtPointer call)
  49. {
  50.     int i;
  51.  
  52.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  53.  
  54.     if (faces) {
  55.     for (i = 0; i < SIZE; i++) {
  56.         glDrawArraysEXT(GL_QUAD_STRIP, i * 2 * SIZE, 2*SIZE);
  57.     }
  58.     } else {
  59.     for (i = 0; i < SIZE; i++) {
  60.         glDrawArraysEXT(GL_LINES, i * 2 * SIZE, 2*SIZE);
  61.     }
  62.     }
  63.     
  64. }
  65.  
  66. static void 
  67. initialize(void)
  68. {
  69.     float x0, y0, z0, x1, y1, z1;
  70.     GLfloat height[SIZE + 2][SIZE + 2];
  71.     int i, j;
  72.  
  73.     /*
  74.      * set up an array from which to read the heights.  THIS IS NOT
  75.      * THE VERTEX ARRAY.  this is a lookup table from which we will
  76.      * make the vertex array.  it is one wider and one higher than the
  77.      * actual grid because of how it is used to compute normals. */
  78.     for (i = 0; i < SIZE + 2; i++) 
  79.        for (j = 0; j < SIZE + 2; j++) {
  80.        height[j][i] = sin(i) + cos(j); 
  81.        }
  82.  
  83.     /* 
  84.      * set up the vertex arrays using the lookup table.  we will draw
  85.      * the array as SIZE independent quad strips.  
  86.      */
  87.     for (i = 0; i < SIZE; i++) {
  88.     for (j = 0; j < SIZE; j++) {
  89.         vertexes[i][j][0][0] = i;
  90.         vertexes[i][j][0][1] = j;
  91.         vertexes[i][j][0][2] = height[i][j];
  92.  
  93.         vertexes[i][j][1][0] = i + 1;
  94.         vertexes[i][j][1][1] = j;
  95.         vertexes[i][j][1][2] = height[i + 1][j];
  96.     }
  97.     }
  98.     glVertexPointerEXT(3, GL_FLOAT, 0, 
  99.                sizeof(vertexes) / sizeof(vertexes[0][0][0]),
  100.                (const GLvoid *)&vertexes[0][0][0][0]);
  101.     glEnable(GL_VERTEX_ARRAY_EXT);
  102.  
  103.  
  104.  
  105.     /* 
  106.      * set up the normal at vertex (x, y) as the cross product of (x,
  107.      * y) -- (x + 1, y) and (x, y) -- (x, y + 1).  
  108.      */
  109.     for (i = 0; i < SIZE; i++) {
  110.     for (j = 0; j < SIZE; j++) {
  111.         normals[i][j][0][0] = -height[i+1][j];
  112.         normals[i][j][0][1] = -height[i][j+1];
  113.         normals[i][j][0][2] = 1;
  114.  
  115.         normals[i][j][1][0] = -height[i+2][j];
  116.         normals[i][j][1][1] = -height[i+1][j+1];
  117.         normals[i][j][1][2] = 1;
  118.            
  119.     }
  120.     }
  121.     glNormalPointerEXT(GL_FLOAT, 0, 
  122.                sizeof(normals) / sizeof(normals[0][0][0]),
  123.                (const GLvoid *)&normals[0][0][0][0]);
  124.     if (lighting) glEnable(GL_NORMAL_ARRAY_EXT);
  125.     /* normals are not normalized so turn on autonormalization */
  126.     glEnable(GL_NORMALIZE);
  127.  
  128.  
  129.  
  130.     /* 
  131.      * set up the colors as a simple ramp of the form:
  132.      * r = x / SIZE
  133.      * g = y / SIZE
  134.      * b = ((x + y) / 2) / SIZE
  135.      */
  136.     for (i = 0; i < SIZE; i++) {
  137.     for (j = 0; j < SIZE; j++) {
  138.         colors[j][i][0][0] = (float)i / (float)SIZE * 255.0;
  139.         colors[j][i][0][1] = (float)j / (float)SIZE * 255.0;
  140.         colors[j][i][0][2] = ((float)(i + j) / 2.0) / (float)SIZE * 255.0;
  141.  
  142.         colors[j][i][1][0] = (float)i / (float)SIZE * 255.0;
  143.         colors[j][i][1][1] = (float)(j + 1) / (float)SIZE * 255.0;
  144.         colors[j][i][1][2] = 
  145.            ((float)(i + 1 + j)/2.0) / (float)SIZE * 255.0;
  146.     }
  147.     }
  148.     glColorPointerEXT(3, GL_UNSIGNED_BYTE, 0, 
  149.               sizeof(colors) / sizeof(colors[0][0][0]),
  150.               (const GLvoid *)&colors[0][0][0][0]);
  151.     if (!lighting) glEnable(GL_COLOR_ARRAY_EXT);
  152.  
  153.  
  154.     glEnable(GL_DEPTH_TEST);
  155.     glEnable(GL_LIGHT0);
  156.     if (lighting) {
  157.     glEnable(GL_LIGHTING);
  158.     }
  159.  
  160.  
  161.     glMatrixMode(GL_PROJECTION);
  162.     glLoadIdentity();
  163.     gluPerspective(45, 1, 1, SIZE * 4);
  164.  
  165.     glMatrixMode(GL_MODELVIEW);
  166.     glLoadIdentity();
  167.     gluLookAt(-SIZE, -SIZE, 12,
  168.           SIZE, SIZE, 0, 
  169.           0, 0, 1);
  170. }
  171.  
  172. static void
  173. process_input(Widget w, XtPointer client_data, XtPointer call)
  174. {
  175.     int redraw = 0;
  176.     XEvent *event = ((GLwDrawingAreaCallbackStruct *) call)->event;
  177.     char buf[31];
  178.     KeySym keysym;
  179.  
  180.  
  181.     switch(event->type) {
  182.       case KeyRelease:
  183.     (void) XLookupString(&event->xkey, buf, sizeof(buf), &keysym, NULL);
  184.     if (keysym == XK_Escape) {
  185.         exit(EXIT_SUCCESS);
  186.     }
  187.         
  188.     /* simple state machine to cycle through all combinations of
  189.      * lighting & drawing faces.  although we do not have to
  190.      * en/disable the normal array, it will result in passing less
  191.      * stuff down the pipe.  */
  192.     if (!lighting && !faces) {
  193.         lighting = 1;
  194.         glEnable(GL_LIGHTING);
  195.         glEnable(GL_NORMAL_ARRAY_EXT);
  196.         glDisable(GL_COLOR_ARRAY_EXT);
  197.     } else if (lighting && !faces) {
  198.         faces = 1;
  199.     } else if (lighting && faces) {
  200.         lighting = 0;
  201.         glDisable(GL_LIGHTING);
  202.         glDisable(GL_NORMAL_ARRAY_EXT);
  203.         glEnable(GL_COLOR_ARRAY_EXT);
  204.     } else if (!lighting && faces) {
  205.         faces = 0;
  206.     }
  207.     redraw = 1;
  208.     break;
  209.       default:
  210.     break;
  211.     }
  212.  
  213.     if (redraw) draw_scene(w, 0, 0);
  214. }
  215.     
  216.  
  217. main(int argc, char *argv[])
  218. {
  219.     Display *dpy;
  220.     XVisualInfo *visinfo;
  221.     GLXContext glxcontext;
  222.     Widget toplevel, frame, glxwidget;
  223.     XtAppContext appctx;
  224.     
  225.     toplevel = XtOpenApplication(&appctx, "vertarray", NULL, 0, 
  226.                  &argc, argv, fallbackResources, 
  227.                  applicationShellWidgetClass, NULL, 0);
  228.     dpy = XtDisplay(toplevel);
  229.     
  230.     frame = XmCreateFrame(toplevel, "frame", NULL, 0);
  231.     XtManageChild(frame);
  232.     
  233.     /* specify visual directly */
  234.     if (!(visinfo = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList)))
  235.        XtAppError(appctx, "no suitable RGB visual");
  236.     
  237.     glxwidget = XtVaCreateManagedWidget("glxwidget", 
  238.                     glwMDrawingAreaWidgetClass,
  239.                     frame, GLwNvisualInfo, 
  240.                     visinfo, NULL);
  241.     XtAddCallback(glxwidget, GLwNexposeCallback, draw_scene, NULL);
  242.     XtAddCallback(glxwidget, GLwNresizeCallback, reshape, NULL);
  243.     XtAddCallback(glxwidget, GLwNinputCallback, process_input, NULL);
  244.  
  245.     XtRealizeWidget(toplevel);
  246.  
  247.     glxcontext = glXCreateContext(dpy, visinfo, 0, GL_TRUE);
  248.     GLwDrawingAreaMakeCurrent(glxwidget, glxcontext);
  249.  
  250.     initialize();
  251.  
  252.     printf("hit any key to toggle drawing mode, ESC to exit.\n");
  253.  
  254.     XtAppMainLoop(appctx);
  255. }
  256.  
  257.